package com.attendance.www.hr.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;

import com.attendance.www.hr.beans.SalaryBean;
import com.attendance.www.hr.beans.SalaryListBean;
import com.attendance.www.hr.beans.SalaryRequestBean;
import com.attendance.www.hr.beans.SalaryRequestPageBean;
import com.attendance.www.hr.dao.mapper.CorporationMapper;
import com.attendance.www.hr.dao.mapper.EmployeeMapper;
import com.attendance.www.hr.dao.mapper.SalaryApprovalRecordMapper;
import com.attendance.www.hr.dao.mapper.SalaryExtMapper;
import com.attendance.www.hr.dao.mapper.SalaryMapper;
import com.attendance.www.hr.dao.mapper.SalaryRequestExtMapper;
import com.attendance.www.hr.dao.mapper.SalaryRequestMapper;
import com.attendance.www.hr.dao.mapper.SalaryRuleMapper;
import com.attendance.www.hr.entitys.Corporation;
import com.attendance.www.hr.entitys.CorporationExample;
import com.attendance.www.hr.entitys.Employee;
import com.attendance.www.hr.entitys.EmployeeExample;
import com.attendance.www.hr.entitys.Salary;
import com.attendance.www.hr.entitys.SalaryApprovalRecord;
import com.attendance.www.hr.entitys.SalaryApprovalRecordExample;
import com.attendance.www.hr.entitys.SalaryExample;
import com.attendance.www.hr.entitys.SalaryExample.Criteria;
import com.attendance.www.hr.entitys.SalaryRequest;
import com.attendance.www.hr.entitys.SalaryRule;
import com.attendance.www.hr.entitys.SalaryRuleExample;
import com.attendance.www.hr.exception.ResultFaultException;
import com.attendance.www.hr.service.IApprovalService;
import com.attendance.www.hr.service.ISalaryRequestService;
import com.attendance.www.hr.service.ISalaryService;

@Service
public class SalaryRequestServiceImpl implements ISalaryRequestService {

	@Resource
	private EmployeeMapper employeeDao;
	@Resource
	private SalaryRequestMapper salaryRequestDao;
	@Resource
	private SalaryRequestExtMapper salaryRequestExtDao;
	@Resource
	private SalaryRuleMapper salaryRuleDao;
	@Resource
	private SalaryMapper salaryDao;
	@Resource
	private CorporationMapper corporationDao;
	@Resource
	private SalaryApprovalRecordMapper salaryApprovalRecordDao;
	@Resource
	private IApprovalService approvalService;
	@Resource
	private ISalaryService salaryService;
	@Resource
	private SalaryExtMapper salaryExtDao;
	
	/**
	 * 查询工资报表提交历史
	 */
	@Override
	public SalaryRequestPageBean getSalaryRequestList(SalaryRequestBean salaryRequestBean) {
		// TODO Auto-generated method stub
		Employee emp = employeeDao.selectByPrimaryKey(salaryRequestBean.getEmployeeId());
		salaryRequestBean.setEmployeeNoSubmit(emp.getEmployeeNo());
		SalaryRequestPageBean salaryRequestPageBean = new SalaryRequestPageBean();
		salaryRequestPageBean.setPageTotal(salaryRequestExtDao.count(salaryRequestBean));
		salaryRequestPageBean.setSalaryRequestBeanList(salaryRequestExtDao.getSalaryRequestList(salaryRequestBean));
		return salaryRequestPageBean;
	}

	/**
	 * 提交工资报表申请("提交"按钮)
	 */
	@Override
	public boolean saveSalaryRequestList(SalaryListBean salaryListBean) {
		Date startDate = salaryListBean.getStartDate();
		Date endDate = salaryListBean.getEndDate();
		Date historyStartDate = salaryListBean.getHistoryStartDate();
		Date historyEndDate = salaryListBean.getHistoryEndDate();
		if (startDate==null && endDate==null) {
			startDate = historyStartDate;
			endDate = historyEndDate;
		}
		int record = 0;
		//查询申请人
		Employee emp = employeeDao.selectByPrimaryKey(salaryListBean.getEmployeeId());
		String employeeNoSubmit = emp.getEmployeeNo();
		
		//验证日期
		if (this.getVerifyDate(startDate, endDate,salaryListBean.getCorporationList(),employeeNoSubmit)) {
			throw new ResultFaultException("16_00008");//提交日期有误
		}
		
		int salaryYear = salaryListBean.getSalaryYear();
		int salaryMonth = salaryListBean.getSalaryMonth();
		//审批规则id
		int salaryRuleId = 0;
		
		//查询工资报表审批规则
		List<SalaryRule> srList = salaryRuleDao.selectByExample(new SalaryRuleExample());
		SalaryRule salaryRule = new SalaryRule();
		if (srList.size()>0) {
			salaryRule = srList.get(0);
			salaryRuleId = salaryRule.getSalaryRuleId();
		} else {
			throw new ResultFaultException("16_00004");//无审批规则
		}
		SalaryRequest salaryRequest = new SalaryRequest();
		salaryRequest.setDescription(salaryListBean.getDescription());
		salaryRequest.setEmployeeNoSubmit(employeeNoSubmit);
		salaryRequest.setChineseName(emp.getChineseName());
		salaryRequest.setRequestDate(new Date());
		salaryRequest.setRequestState(1);//1 申请中
		salaryRequest.setSalaryMonth(salaryMonth);
		salaryRequest.setSalaryRuleId(salaryRuleId);
		salaryRequest.setSalaryYear(salaryYear);
		salaryRequest.setStartDate(startDate);
		salaryRequest.setEndDate(endDate);
		record = salaryRequestDao.insertSelective(salaryRequest);
		if (record<=0) {
			return false;
		}
		
		//修改工资报表信息申请状态，添加申请id
		Salary salary = new Salary();
		SalaryExample salaryExample = new SalaryExample();
		//提交人编号，年份，月份，（公司），三（或四）条件筛选
		Criteria criteria=salaryExample.createCriteria();
		criteria.andEmployeeNoSubmitEqualTo(employeeNoSubmit)
		.andStartDateEqualTo(startDate)
		.andEndDateEqualTo(endDate);
		//by公司提交
		if (salaryListBean.getCorporationList()!=null && salaryListBean.getCorporationList().size()>0) {
			//查现有公司
			Map<String, String> cMap = new HashMap<>();//匹配公司code和公司名name
			CorporationExample corporationExample = new CorporationExample();
			corporationExample.or().andIsDeleteEqualTo(0)
			.andFromDateLessThanOrEqualTo(new Date())
			.andThruDateGreaterThanOrEqualTo(new Date());
			corporationExample.or().andIsDeleteEqualTo(0)
			.andFromDateLessThanOrEqualTo(new Date())
			.andThruDateIsNull();
			List<Corporation> cList = corporationDao.selectByExample(corporationExample);
			for (Corporation corporation : cList) {
				cMap.put(corporation.getCorporationCode(), corporation.getCorporationName());
			}
			//公司Name List
			List<String> corporationNameList = new ArrayList<>();
			//公司编号参数List
			List<String> corListParam = salaryListBean.getCorporationList();
			for (String corNo : corListParam) {
				
				if (cMap.containsKey(corNo)) {
					corporationNameList.add(cMap.get(corNo));
				}
			}
			criteria.andDeptmentNameOneIn(corporationNameList);
		}
		//查询是否已生成报表，提交的信息是否为空
		List<Salary> salaryList = salaryDao.selectByExample(salaryExample);
		if (salaryList.size()==0) {
			throw new ResultFaultException("16_00003");
		}
		//更新 主报表数据的申请id和申请状态
		salary.setRequestState(1);
		salary.setSalaryRequestId(salaryRequest.getSalaryRequestId());
		salary.setSalaryYear(salaryYear);
		salary.setSalaryMonth(salaryMonth);
		record = salaryDao.updateByExampleSelective(salary, salaryExample);
		if (record<=0) {
			return false;
		}
		//添加审批记录
		String employeeNoApproval = salaryRule.getOneEmployeeNo();//审批人编号
		SalaryApprovalRecord salaryApprovalRecord = new SalaryApprovalRecord();
		salaryApprovalRecord.setApprovalState(1);//1 审批中
		salaryApprovalRecord.setEmployeeNoSubmit(employeeNoSubmit);
		salaryApprovalRecord.setStep(1);
		salaryApprovalRecord.setEmployeeNoApproval(employeeNoApproval);
		salaryApprovalRecord.setSalaryMonth(salaryMonth);
		salaryApprovalRecord.setSalaryRequestId(salaryRequest.getSalaryRequestId());
		salaryApprovalRecord.setSalaryYear(salaryYear);
		record = salaryApprovalRecordDao.insertSelective(salaryApprovalRecord);
		if (record<=0) {
			return false;
		}
		//邮件提醒
		//查审批人id
		EmployeeExample empExample = new EmployeeExample();
		empExample.or().andEmployeeNoEqualTo(employeeNoApproval)
		.andFromDateLessThanOrEqualTo(new Date())
		.andThruDateIsNull();
		empExample.or().andEmployeeNoEqualTo(employeeNoApproval)
		.andFromDateLessThanOrEqualTo(new Date())
		.andThruDateGreaterThanOrEqualTo(new Date());
		
		List<Employee> empList = employeeDao.selectByExample(empExample);
		if (empList.size()>0) {
			Integer employeeId = empList.get(0).getEmployeeId();
			String textPart = "员工："+ emp.getChineseName() +"的考勤报表（工资使用）申请待审批，请及时登陆HR考勤管理系统查看";
			approvalService.sendEmail(employeeId,textPart,salaryRequest.getSalaryRequestId(), 88);
		}
		return true;
	}
	
	/**
	 * by审批人查询申请信息
	 */
	@Override
	public SalaryRequestPageBean getSalaryRequestListByApl(SalaryRequestBean salaryRequestBean) {
		// TODO Auto-generated method stub
		Employee emp = employeeDao.selectByPrimaryKey(salaryRequestBean.getEmployeeId());
		salaryRequestBean.setEmployeeNoApproval(emp.getEmployeeNo());
		SalaryRequestPageBean salaryRequestPageBean = new SalaryRequestPageBean();
		salaryRequestPageBean.setPageTotal(salaryRequestExtDao.countByApl(salaryRequestBean));
		salaryRequestPageBean.setSalaryRequestBeanList(salaryRequestExtDao.getSalaryRequestListByApl(salaryRequestBean));
		return salaryRequestPageBean;
	}

	/**
	 * 撤回申请
	 */
	@Override
	public boolean getBackSalaryRequest(Integer salaryRequestId) {
		//requestState改为0（未提交），删除审批记录（必须是未审批的）
		SalaryRequest salaryRequest=salaryRequestDao.selectByPrimaryKey(salaryRequestId);
		salaryRequest.setRequestState(0);
		salaryRequest.setUpdateTime(null);//设置更新时间
		int record=salaryRequestDao.updateByPrimaryKeySelective(salaryRequest);
		if(record<=0){
			return false;
		}
		//更新主数据申请状态
		Salary salary = new Salary();
		SalaryExample salaryExample = new SalaryExample();
		salaryExample.createCriteria().andSalaryRequestIdEqualTo(salaryRequestId);
		
		salary.setRequestState(0);//主数据requestState改为0（未提交）
		record = salaryDao.updateByExampleSelective(salary, salaryExample);
		if (record<=0) {
			return false;
		}
		//删除审批记录
		SalaryApprovalRecordExample sarExample = new SalaryApprovalRecordExample();
		sarExample.createCriteria().andSalaryRequestIdEqualTo(salaryRequestId);
		salaryApprovalRecordDao.deleteByExample(sarExample);
		return true;
	}

	/**
	 * 撤回申请验证
	 * true 不能撤回，false 可以撤回
	 */
	@Override
	public boolean verifyGetBackRequest(Integer salaryRequestId) {
		SalaryApprovalRecordExample sarExample = new SalaryApprovalRecordExample();
		sarExample.createCriteria().andSalaryRequestIdEqualTo(salaryRequestId);
		List<SalaryApprovalRecord> arList=salaryApprovalRecordDao.selectByExample(sarExample);
		if (arList.size()>1) {
			return true;
		} else if(arList.size() == 1){
			Integer isApprove=arList.get(0).getApprovalState();
			if (isApprove != 1) {
				return true;
			}
		}
		return false;
	}

	/**
	 * 删除申请
	 */
	@Override
	public boolean deleteSalaryRequest(Integer salaryRequestId) {
		int record=salaryRequestDao.deleteByPrimaryKey(salaryRequestId);
		if(record<=0){
			return false;
		}
		//更新报表数据的申请id和申请状态
		Salary salary = new Salary();
		SalaryExample salaryExample = new SalaryExample();
		salaryExample.createCriteria().andSalaryRequestIdEqualTo(salaryRequestId);
		salary.setSalaryRequestId(0);//让被删除申请关联的数据的申请id为0
		salary.setRequestState(0);//主数据requestState改为0（未提交）
		record = salaryDao.updateByExampleSelective(salary, salaryExample);
		/*if (record<=0) {
			return false;
		}*/
		return true;
	}

	/**
	 * 获取报表年月
	 */
	@Override
	public SalaryListBean getYearMonth(SalaryBean salaryBean) {
		// TODO Auto-generated method stub
		Employee emp = employeeDao.selectByPrimaryKey(salaryBean.getEmployeeId());
		String employeeNoSubmit = emp.getEmployeeNo();

		//要查询的公司Name List
		List<String> corporationNameList = new ArrayList<>();
		//
		if (salaryBean.getCorporationList()!=null && salaryBean.getCorporationList().size()>0) {
			//查现有公司
			Map<String, String> cMap = new HashMap<>();//匹配公司code和公司名name
			CorporationExample corporationExample = new CorporationExample();
			corporationExample.or().andIsDeleteEqualTo(0)
			.andFromDateLessThanOrEqualTo(new Date())
			.andThruDateGreaterThanOrEqualTo(new Date());
			corporationExample.or().andIsDeleteEqualTo(0)
			.andFromDateLessThanOrEqualTo(new Date())
			.andThruDateIsNull();
			List<Corporation> cList = corporationDao.selectByExample(corporationExample);
			for (Corporation corporation : cList) {
				cMap.put(corporation.getCorporationCode(), corporation.getCorporationName());
			}
			//公司编号参数List
			List<String> corListParam = salaryBean.getCorporationList();
			//保存公司名称
			for (String corNo : corListParam) {
				if (cMap.containsKey(corNo)) {
					corporationNameList.add(cMap.get(corNo));
				}
			}
		}
		
		salaryBean.setEmployeeNoSubmit(employeeNoSubmit);
		salaryBean.setCorporationNameList(corporationNameList);
		//返回每个公司对应年份月份的参数
		List<SalaryBean> salaryBeanList = salaryExtDao.getSalaryYearMonth(salaryBean);
		boolean isSameYear = true;
		boolean isSameMonth = true;
		SalaryListBean salaryListBean = new SalaryListBean();
		
		if (salaryBeanList.size()==0) {//没有过记录
			List<String> errorList = new ArrayList<>();
			errorList.add("首次保存，请手选年份月份。");
			salaryListBean.setErrorList(errorList);
			return salaryListBean;
		} else if (salaryBeanList.size()>1) {//有两条及以上
			int year = 0;
			int month = 0;
			for (SalaryBean salaryBean2 : salaryBeanList) {
				if (year==0) {
					year = salaryBean2.getSalaryYear();
				} else if (year != salaryBean2.getSalaryYear()) {
					isSameYear=false;
				}
				if (month==0) {
					month = salaryBean2.getSalaryMonth();
				} else if (month != salaryBean2.getSalaryMonth()) {
					isSameMonth=false;
				}
			}
		}
		
		if (isSameMonth && isSameYear) {//同一个时间
			int salaryYear = salaryBeanList.get(0).getSalaryYear();
			int salaryMonth = salaryBeanList.get(0).getSalaryMonth();
			//判断是否是12月
			if (salaryMonth==12) {
				salaryYear = salaryYear +1;
				salaryMonth = 1;
			} else {
				salaryMonth = salaryMonth+1;
			}
			salaryListBean.setSalaryYear(salaryYear);
			salaryListBean.setSalaryMonth(salaryMonth);
		} else {
			List<String> errorList = new ArrayList<>();
			for (SalaryBean salaryBean2 : salaryBeanList) {
				errorList.add(salaryBean2.getDeptmentNameOne()+"上次提交的"+salaryBean2.getSalaryYear()+"年"
						+salaryBean2.getSalaryMonth()+"月的工资报表。");
			}
			salaryListBean.setErrorList(errorList);
		}
		return salaryListBean;
	}

	/**
	 * 验证提交报表的日期，
	 * 是否同一公司的
	 * 同一个申请人的
	 * 日期是否有重叠
	 */
	@Override
	public boolean getVerifyDate(Date startDate, Date endDate, List<String> corporationCodeList, String employeeNo) {
		//申请状态List（1和2的）
		List<Integer> requestStateList = new ArrayList<>();
		requestStateList.add(1);
		requestStateList.add(2);
		//公司nameList
		//要查询的公司Name List
		List<String> corporationNameList = new ArrayList<>();
		//by公司提交
		if (corporationCodeList!=null && corporationCodeList.size()>0) {
			//查现有公司
			Map<String, String> cMap = new HashMap<>();//匹配公司code和公司名name
			CorporationExample corporationExample = new CorporationExample();
			corporationExample.or().andIsDeleteEqualTo(0)
			.andFromDateLessThanOrEqualTo(new Date())
			.andThruDateGreaterThanOrEqualTo(new Date());
			corporationExample.or().andIsDeleteEqualTo(0)
			.andFromDateLessThanOrEqualTo(new Date())
			.andThruDateIsNull();
			List<Corporation> cList = corporationDao.selectByExample(corporationExample);
			for (Corporation corporation : cList) {
				cMap.put(corporation.getCorporationCode(), corporation.getCorporationName());
			}
			//公司编号参数List
			//保存公司名称
			for (String corNo : corporationCodeList) {
				if (cMap.containsKey(corNo)) {
					corporationNameList.add(cMap.get(corNo));
				}
			}
		} else {//比较全部的公司
			//查现有公司
			CorporationExample corporationExample = new CorporationExample();
			corporationExample.or().andIsDeleteEqualTo(0)
			.andFromDateLessThanOrEqualTo(new Date())
			.andThruDateGreaterThanOrEqualTo(new Date());
			corporationExample.or().andIsDeleteEqualTo(0)
			.andFromDateLessThanOrEqualTo(new Date())
			.andThruDateIsNull();
			List<Corporation> cList = corporationDao.selectByExample(corporationExample);
			for (Corporation corporation : cList) {
				corporationNameList.add(corporation.getCorporationName());
			}
		}
		
		SalaryExample salaryExample = new SalaryExample();
		salaryExample.or().andRequestStateIn(requestStateList)
		.andDeptmentNameOneIn(corporationNameList)
		.andStartDateLessThanOrEqualTo(startDate)
		.andEndDateGreaterThanOrEqualTo(startDate)
		.andEmployeeNoSubmitEqualTo(employeeNo);
		
		salaryExample.or().andRequestStateIn(requestStateList)
		.andDeptmentNameOneIn(corporationNameList)
		.andStartDateLessThanOrEqualTo(endDate)
		.andEndDateGreaterThanOrEqualTo(endDate)
		.andEmployeeNoSubmitEqualTo(employeeNo);
		
		List<Salary> sList = salaryDao.selectByExample(salaryExample);
		if (sList.size()>0) {
			return true;
		}
		return false;
	}

	/**
	 * 撤回后再次提交，对应提交历史页"提交"按钮
	 */
	@Override
	public boolean saveSalaryRequestAgain(Integer salaryRequestId) {
		// TODO Auto-generated method stub
		int record = 0;
		
		//验证申请记录对应的主数据，是否存在，是否被替换了
		SalaryExample salaryExample = new SalaryExample();
		salaryExample.createCriteria().andSalaryRequestIdEqualTo(salaryRequestId);
		List<Salary> salaryList = salaryDao.selectByExample(salaryExample);
		if (salaryList.size()==0) {
			//替换了，弹出throw，请删除此申请
			throw new ResultFaultException("16_00009");//提交日期有误
		}
		//修改主数据申请状态
		Salary salary = new Salary();
		salary.setRequestState(1);//1（提交）
		salary.setSalaryRequestId(salaryRequestId);//主数据关联的申请id
		record = salaryDao.updateByExampleSelective(salary, salaryExample);
		if (record<=0) {
			return false;
		}
		
		//update提交申请，更改申请状态
		SalaryRequest salaryRequestDB = salaryRequestDao.selectByPrimaryKey(salaryRequestId);
		
		salaryRequestDB.setRequestDate(new Date());
		salaryRequestDB.setRequestState(1);//1，申请中
		//置空create time，update time，--》null
		salaryRequestDB.setCreateTime(null);
		salaryRequestDB.setUpdateTime(null);
		record = salaryRequestDao.updateByPrimaryKeySelective(salaryRequestDB);
		if (record<=0) {
			return false;
		}
		
		//添加审批记录
		//查询工资报表审批规则
		List<SalaryRule> srList = salaryRuleDao.selectByExample(new SalaryRuleExample());
		SalaryRule salaryRule = new SalaryRule();
		if (srList.size()>0) {
			salaryRule = srList.get(0);
		} else {
			throw new ResultFaultException("16_00004");//无审批规则
		}
		String employeeNoApproval = salaryRule.getOneEmployeeNo();//审批人编号
		SalaryApprovalRecord salaryApprovalRecord = new SalaryApprovalRecord();
		salaryApprovalRecord.setApprovalState(1);//1 审批中
		salaryApprovalRecord.setEmployeeNoSubmit(salaryRequestDB.getEmployeeNoSubmit());
		salaryApprovalRecord.setStep(1);
		salaryApprovalRecord.setEmployeeNoApproval(employeeNoApproval);
		salaryApprovalRecord.setSalaryMonth(salaryRequestDB.getSalaryMonth());
		salaryApprovalRecord.setSalaryRequestId(salaryRequestId);
		salaryApprovalRecord.setSalaryYear(salaryRequestDB.getSalaryYear());
		record = salaryApprovalRecordDao.insertSelective(salaryApprovalRecord);
		if (record<=0) {
			return false;
		}
		//邮件提醒
		//查审批人id
		EmployeeExample empExample = new EmployeeExample();
		empExample.or().andEmployeeNoEqualTo(employeeNoApproval)
		.andFromDateLessThanOrEqualTo(new Date())
		.andThruDateIsNull();
		empExample.or().andEmployeeNoEqualTo(employeeNoApproval)
		.andFromDateLessThanOrEqualTo(new Date())
		.andThruDateGreaterThanOrEqualTo(new Date());
		
		List<Employee> empList = employeeDao.selectByExample(empExample);
		if (empList.size()>0) {
			Integer employeeId = empList.get(0).getEmployeeId();
			approvalService.sendEmail(employeeId, "有"+salaryRequestDB.getChineseName()+"的考勤报表（工资使用）申请，请及时登陆HR考勤管理系统查看。",
					salaryRequestId, 88);
		}
		return true;
	}

}
